<?php
/**
 * @file
 * Contains \Drupal\gdlisnet\Entity\CollectionStorage.
 */

namespace Drupal\gdlisnet\Entity;

require_once 'File/MARC.php';

use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Entity\EntityStorageBase;
use Drupal\Core\Entity\EntityTypeInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;

use File_MARC_Record;
use File_MARC_Control_Field;
use File_MARC_Data_Field;
use File_MARC_Subfield;

/**
 * Defines the storage class for collection entities.
 *
 */
class CollectionStorage extends EntityStorageBase {
	const MARC_TYPE_USMARC=0;
	const MARC_TYPE_CNMARC=1;

	protected static $oci_resource;
	
	private static function connectDatabase() {
		$gdlisnet_database = \Drupal::config('gdlisnet.datasource');
		if(empty(self::$oci_resource)) {
			$conn=oci_pconnect($gdlisnet_database->get('username'), $gdlisnet_database->get('password'),
				sprintf("%s:%s/%s", $gdlisnet_database->get('host'), $gdlisnet_database->get('port'), $gdlisnet_database->get('database')), 'AL32UTF8'
			);
			if($conn) {
				self::$oci_resource=$conn;
			} else {
				$e=oci_error();
				\Drupal::logger('gdlisnet')->error('Gdlisnet database settings error(@errcode): @errmsg.',
					array('@errcode'=>$e['code'], '@errmsg'=>$e['message'])
				);
			}
		}
	}
	
	/**
	* {@inheritdoc}
	*/
	protected function doLoadMultiple(array $ids = NULL) {
		self::connectDatabase();
		$entities=[];
		foreach($ids as $id) {
			$sql=sprintf("SELECT 馆藏书目库.*, MARC_DATA.MARC1, MARC_DATA.MARC2, MARC_DATA.MARC3, 书目数据库定义.MARC类型 FROM 馆藏书目库 ".
				"INNER JOIN MARC_DATA ON 馆藏书目库.主键码=MARC_DATA.主键码 ".
				"INNER JOIN 书目数据库定义 ON 馆藏书目库.库键码=书目数据库定义.库键码 ".
				"WHERE 馆藏书目库.主键码=%s AND EXISTS(".
				"SELECT * FROM 馆藏典藏库 WHERE 馆藏典藏库.状态='G' AND 馆藏典藏库.主键码=馆藏书目库.主键码)", $id);
			$stmt = @oci_parse(self::$oci_resource, $sql);
			$r=@oci_execute($stmt, OCI_DEFAULT);
			if($r) {
				$a=oci_fetch_array($stmt);
				if($a) {
					$entities[$id]=$a;
					// Integrate marc data
					$entities[$id]['marc_raw']=$entities[$id]['MARC1'].$entities[$id]['MARC2'].$entities[$id]['MARC3'];
					// structured marc data
					$fields=array_filter(explode(chr(0x1e), $entities[$id]['marc_raw']));
					$record=new File_MARC_Record();
					foreach($fields as $key=>$field) {
						if($key==0) {
							$record->setLeader($field);
						} else {
							$tag=substr($field, 0, 3);
							if(strpos($field, 0x1f)) {
								$data=array_filter(explode(chr(0x1f), substr($field,5)));
								$subfields=[];
								foreach($data as $d) {
									$subfields[]=new File_MARC_Subfield(substr($d,0,1), substr($d,1));
								}
								$data_field=new File_MARC_Data_Field($tag, $subfields, substr($field,3,1), substr($field,4,1));
								$record->appendField($data_field);
							} else {
								$tag=substr($field, 0, 3);
								$control_field=new File_MARC_Control_Field($tag, substr($field,3));
								$record->appendField($control_field);
							}
						}
					}
					$entities[$id]['marc']=$record;
					if($entities[$id]['MARC类型']=='0') $entities[$id]['MARC类型']=self::MARC_TYPE_USMARC;
					else $entities[$id]['MARC类型']=self::MARC_TYPE_CNMARC;
				}
				else
					$entities[$id]=[];
			}
		}
		if(empty($entities)) return [];
		else {
			return $this->mapFromStorageRecords($entities);
		}
	}
	
	/**
	* {@inheritdoc}
	*/
	protected function has($id, EntityInterface $entity) {
		return FALSE;
	}

	/**
	* {@inheritdoc}
	*/
	protected function doDelete($entities) {
	}

	/**
	* {@inheritdoc}
	*/
	protected function doSave($id, EntityInterface $entity) {
	}

	/**
	* {@inheritdoc}
	*/
	protected function getQueryServiceName() {
		return 'gdlisnet';
	}

	public function loadRevision($revision_id) {
		return NULL;
	}
	public function deleteRevision($revision_id) {
		return NULL;
	}

	/**
	* Constructs a CollectionEntityStorage object.
	*
	* @param \Drupal\Core\Entity\EntityTypeInterface $entity_type
	*   The entity type definition.
	*/
	public function __construct(EntityTypeInterface $entity_type) {
		self::connectDatabase();
		parent::__construct($entity_type);
	}

	/**
	* {@inheritdoc}
	*/
	public static function createInstance(ContainerInterface $container, EntityTypeInterface $entity_type) {
		return new static($entity_type);
	}
}
